from umqtt.simple import MQTTClient
import ubinascii
import machine
import time
from oled import update_text
from temperature import register_Temperature_topic, temperature_callback
from led import register_led_Topic, handleLed
from humanbody import register_humanbody_Topic
from soilmoisture import register_soilmoisture_topic, soilmoisture_callback
from dht11 import register_dht11_topic, dht11_callback

client = None
# MQTT服务配置
MQTT_SERVER = "10.218.44.25"
MQTT_PORT = 1883  # 默认 MQTT 不加密端口
MQTT_USER = "fisher"
MQTT_PASSWORD = "123456"
CLIENT_ID = ubinascii.hexlify(machine.unique_id()).decode("utf-8")
KEEPALIVE = 60


def config_mqtt():
    global client
    attempt = 0  # 重连尝试次数
    while True:  # 持续连接和接收消息的循环
        try:
            print("Connecting to MQTT broker...")
            connect_and_subscribe()
            attempt = 0  # 重置重连尝试次数
            while True:  # 消息检查循环
                client.check_msg()
                time.sleep(0.1)  # CPU 使用优化
        except OSError as e:
            print("Network related error, trying to restart connection: {}".format(e))
        except Exception as e:
            print("An unexpected error occurred: {}".format(e))
        # 这里实现退避逻辑
        attempt += 1
        wait_time = min(30, 2**attempt)  # 指数退避，最大等待时间限制为30秒
        print("Waiting for {} seconds before retry".format(wait_time))
        time.sleep(wait_time)
        # 尝试重新连接之前，先断开现有连接
        if client is not None:
            try:
                client.disconnect()
            except Exception:
                pass
            client = None


def main_timer_callback(t):
    temperature_res = temperature_callback(t)
    soilmoisture_res = soilmoisture_callback(t)
    dht11_res = dht11_callback(t)
    print("temperature_callback:", temperature_res)
    print("soilmoisture_callback:", soilmoisture_res)
    print("dht11_callback:", dht11_res)
    update_text(
        soilmoisture=soilmoisture_res,
        temperature=dht11_res["temp"],
        humidity=dht11_res["hum"],
    )


def connect_and_subscribe():
    global client  # 声明使用全局变量
    # 创建 MQTT 客户端
    if client is None:  # 防止重复创建客户端实例
        client = MQTTClient(
            CLIENT_ID,
            MQTT_SERVER,
            MQTT_PORT,
            MQTT_USER,
            MQTT_PASSWORD,
            keepalive=KEEPALIVE,
        )
    # 指定消息回调
    client.set_callback(on_message)
    try:
        client.connect()
        print("Connected to %s" % (MQTT_SERVER))
        register_soilmoisture_topic(client)
        register_led_Topic(client)
        register_Temperature_topic(client)
        register_humanbody_Topic(client)
        register_dht11_topic(client)
        main_timer = machine.Timer(0)
        main_timer.init(
            period=10000, mode=machine.Timer.PERIODIC, callback=main_timer_callback
        )
    except Exception as e:
        print("Could not connect to MQTT server: {}".format(e))
        client = None


# 监听消息
def on_message(topic, msg):
    print("topic:  ", topic.decode())
    print("msg:  ", msg.decode())
    handleLed(topic, msg)


# # 发布消息
# def publish_message():
#     global client  # 声明 client 为全局变量
#     # 发布消息
#     client.publish(TOPIC, b"Hello ESP32")
